<template>
  <div id="register">
    <en-header-other title="欢迎注册">
      <div class="have-account">
        <span>已有账号？</span>
        <router-link :to="'/login' + MixinForward">请登录></router-link>
      </div>
    </en-header-other>
    <div class="register-content">
      <el-form
        :model="registerForm"
        :rules="registerRules"
        ref="registerForm"
        :status-icon="false"
        label-width="100px"
      >
        <el-form-item prop="username">
          <span slot="label">用&ensp;户&ensp;名</span>
          <el-input
            v-model="registerForm.username"
            :maxlength="20"
            placeholder="请输入用户名"
            :validate-event="validateEvent"
            @input="input"
          ></el-input>
        </el-form-item>
        <el-form-item label="设置密码" prop="password">
          <el-input
            v-model="registerForm.password"
            type="password"
            :maxlength="20"
            placeholder="密码设置6-20位"
            :validate-event="validateEvent"
            autocompete="off"
            @input="input"
          ></el-input>
        </el-form-item>
        <el-form-item label="确认密码" prop="confirm_password">
          <el-input
            v-model="registerForm.confirm_password"
            type="password"
            :maxlength="20"
            placeholder="请牢记您的密码"
            :validate-event="validateEvent"
            autocompete="off"
            @input="input"
          ></el-input>
        </el-form-item>
        <el-form-item label="手机号码" :error="requiredMobile" prop="mobile">
          <el-input
            v-model="registerForm.mobile"
            :maxlength="11"
            placeholder="请输入手机号"
            :validate-event="validateEvent"
            @input="input"
          ></el-input>
        </el-form-item>
        <template v-if="validateInFO.validator_type === 'ALIYUN'">
          <div style="margin-bottom: 20px">
            <div id="pc-valid" class="nc-container"></div>
          </div>
          <el-form-item prop="sms_code" class="sms-code" v-if="accountAfsSuccess">
            <span slot="label">短信验证码</span>
            <el-input
              v-model="registerForm.sms_code"
              :maxlength="6"
              :placeholder="effectiveMinutes"
              :validate-event="validateEvent"
              @input="input"
            >
              <en-count-down-btn :start="sendValidMobileSms" @end="changeValidCodeUrl" slot="append"/>
            </el-input>
          </el-form-item>
        </template>
        <template v-else-if="validateInFO.validator_type === 'IMAGE'">
          <el-form-item v-if="showValidCode" label="图片验证码" :error="requiredValCode" prop="vali_code" class="vali-code">
            <el-input
              v-model="registerForm.vali_code"
              :maxlength="4"
              placeholder="请输入图片验证码"
              :validate-event="validateEvent"
              @input="input"
            >
              <img v-if="valid_code_url" :src="valid_code_url" slot="append" @click="changeValidCodeUrl">
            </el-input>
          </el-form-item>
          <el-form-item prop="sms_code" class="sms-code">
            <span slot="label">短信验证码</span>
            <el-input
              v-model="registerForm.sms_code"
              :maxlength="6"
              :placeholder="effectiveMinutes"
              :validate-event="validateEvent"
              @input="input"
            >
              <en-count-down-btn :start="sendValidMobileSms" @end="changeValidCodeUrl" slot="append"/>
            </el-input>
          </el-form-item>
        </template>
        <div v-else></div>
        <button type="button" class="register-btn" @click="handleConfirmRegister">立即注册</button>
      </el-form>
    </div>
  </div>
</template>

<script>
import Vue from 'vue'
import { mapActions } from 'vuex'
import * as API_Common from '../api/common'
import * as API_Passport from '../api/passport'
import * as API_Article from '../api/article'
import * as API_Connect from '../api/connect'
import Storage from '../utils/storage'
import AliyunAfs from '../components/AliyunAfs'
import { Button, Form, FormItem, Input } from 'element-ui'
import { RegExp } from '~/ui-utils'

Vue.use(Button).use(Form).use(FormItem).use(Input)

export default {
  name: 'register',
  layout: 'full',
  head() {
    return {
      title: `会员注册-${this.site.title}`
    }
  },
  data() {
    return {
      // uuid
      uuid: Storage.getItem('uuid'),
      // 会员注册 表单
      registerForm: {
        scene: 'REGISTER',
        username: '',
        password: '',
        confirm_password: '',
        mobile: '',
        vali_code: '',
        sms_code: ''
      },
      // 会员注册 表单规则
      registerRules: {
        username: [
          this.MixinRequired('请输入账户名！'),
          { min: 4, max: 20, message: '长度在 4 到 20 个字符' },
          {
            validator: (rule, value, callback) => {
              if (!RegExp.userName.test(value)) {
                callback(new Error('只支持汉字、字母、数字、“-”、“_”的组合！'))
              } else {
                callback()
              }
            }
          },
          {
            validator: (rule, value, callback) => {
              if (!/[^\d]+/.test(value)) {
                callback(new Error('账户名不能为纯数字！'))
              } else {
                callback()
              }
            }
          },
          {
            validator: (rule, value, callback) => {
              API_Passport.checkUsernameRepeat(value).then(response => {
                if (response.exist) {
                  callback(new Error('此用户名已被注册！'))
                } else {
                  callback()
                }
              }).catch(() => {
                callback(new Error('用户名重复校验出错，请稍后再试！'))
              })
            }, trigger: 'blur'
          }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              if (!RegExp.password.test(value)) {
                callback(new Error('密码应为6-20位数字、英文字母，或者特殊字符！'))
              } else {
                callback()
              }
            }
          }
        ],
        confirm_password: [
          { required: true, message: '请确认密码', trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              const { password, confirm_password } = this.registerForm
              if (password !== confirm_password) {
                callback(new Error('两次输入不一致！'))
              } else {
                callback()
              }
            }
          }
        ],
        mobile: [
          this.MixinRequired('请输入手机号码！'),
          {
            validator: (rule, value, callback) => {
              if (!RegExp.mobile.test(value)) {
                callback(new Error('手机格式有误！'))
              } else {
                API_Passport.checkMobileRepeat(value).then(response => {
                  if (response.exist) {
                    callback(new Error('手机号已被注册！'))
                  } else {
                    this.showValidCode = true
                    callback()
                  }
                }).catch(() => {
                  callback(new Error('手机号重复校验出错，请稍后再试！'))
                })
              }
            }
          }
        ],
        vali_code: [this.MixinRequired('请输入图片验证码！')],
        sms_code: [this.MixinRequired('请输入短信验证码！')]
      },
      requiredMobile: '',
      requiredValCode: '',
      // 是否显示图片验证码
      showValidCode: false,
      // 图片验证码URL
      valid_code_url: '',
      // 同意注册协议
      agreed: false,
      // 是否为信任登录
      isConnect: false,
      // 初始化校验事件【兼容IE】
      validateEvent: false,
      // 有效分钟数
      effectiveMinutes: '2分钟内有效',
      // 验证信息
      validateInFO: {},
      // 阿里云验证条实例
      afs: null,
      // 当滑动验证成功之后返回的参数
      afsParam: {
        c_sessionid: '',
        sig: '',
        nc_token: ''
      },
      // 阿里云滑动验证是否通过 && 如果不是 阿里云验证则直接设置为 true
      accountAfsSuccess: false,
      protocol: ''
    }
  },
  beforeRouteLeave(x, y, next) {
    this.$layer && this.$layer.closeAll()
    next()
  },
  mounted() {
    this.changeValidCodeUrl()
    this.getProtocol()
    const uuid_connect = Storage.getItem('uuid_connect')
    const isConnect = this.$route.query.form === 'connect' && !!uuid_connect
    this.isConnect = isConnect
    API_Common.getValidator().then(res => {
      this.validateInFO = res
      const { validator_type, aliyun_afs } = res
      if (validator_type === 'ALIYUN') {
        this.afs = new AliyunAfs('#pc-valid', aliyun_afs.scene, aliyun_afs.app_key, this.initCaptcha)
        this.afs.init()
      } else {
        this.accountAfsSuccess = true
      }
    })
  },
  methods: {
    // 阿里云滑动验证 通过后的回调函数
    initCaptcha(data) {
      this.afsParam.c_sessionid = data.csessionid
      this.afsParam.sig = data.sig
      this.afsParam.nc_token = data.nc_token
      this.accountAfsSuccess = true
    },
    /** 发送手机验证码异步方法 */
    sendValidMobileSms() {
      return new Promise((resolve, reject) => {
        const { mobile, vali_code, scene } = this.registerForm
        if (!mobile) {
          this.$message.error('请输入手机号！')
          this.requiredMobile = '手机号不能为空！'
        } else {
          if (this.afs) {
            const { c_sessionid, sig, nc_token } = this.afsParam
            API_Passport.sendRegisterSliderSms(mobile, c_sessionid, sig, nc_token).then(response => {
              this.effectiveMinutes = `${response}分钟内有效`
              this.$message.success('短信发送成功，请注意查收！')
              resolve()
            }).catch(() => {
              this.afs.reload()
              this.accountAfsSuccess = false
              reject()
            })
          } else {
            if (!vali_code) {
              this.$message.error('请输入图片验证码！')
              this.requiredValCode = '图片验证码不能为空！'
            } else {
              API_Passport.sendRegisterPicSms(mobile, vali_code, scene).then(response => {
                this.effectiveMinutes = `${response}分钟内有效`
                this.$message.success('短信发送成功，请注意查收！')
                resolve()
              }).catch(() => {
                this.changeValidCodeUrl()
                reject()
              })
            }
          }
        }
      })
    },
    /** 获取图片验证码 */
    changeValidCodeUrl() {
      this.valid_code_url = API_Common.getValidateCodeUrl(this.uuid, 'REGISTER')
    },
    /** 输入框输入 */
    input(value) {
      !this.validateEvent && (this.validateEvent = true)
    },
    /** 立即注册 */
    handleConfirmRegister() {
      const _forwardMatch = this.MixinForward.match(/\?forward=(.+)/) || []
      let forward = _forwardMatch[1]
      if (!forward || forward.indexOf('/login') > -1) {
        forward = '/'
      }
      this.$refs['registerForm'].validate(valide => {
        if (valide) {
          const params = JSON.parse(JSON.stringify(this.registerForm))
          if (this.afs) {
            params.c_sessionid = this.afsParam.c_sessionid
            params.sig = this.afsParam.sig
            params.nc_token = this.afsParam.nc_token
            delete params.scene
            delete params.vali_code
          }
          this.registerByMobile(params).then(() => {
            if (this.isConnect) {
              API_Connect.registerBindConnect(Storage.getItem('uuid_connect')).then(() => {
                Storage.removeItem('uuid_connect')
                this.getUserData().then(() => {
                  this.$message.success('注册成功！')
                  setTimeout(() => {
                    this.$router.push({ path: forward || '/member' })
                  }, 200)
                })
              })
            } else {
              this.getUserData().then(() => {
                this.$message.success('注册成功！')
                setTimeout(() => {
                  this.$router.push({ path: forward || '/member' })
                }, 200)
              })
            }
          })
        } else {
          this.$message.error('表单填写有误，请检查！')
          return false
        }
      })
    },
    ...mapActions({
      registerByMobile: 'user/registerByMobileAction',
      getUserData: 'user/getUserDataAction'
    }),
    /** 获取隐私协议 */
    async getProtocol() {
      try {
        this.protocol = await API_Article.getArticleByPosition('REGISTRATION_AGREEMENT')
      } catch (e) {
        this.protocol = { content: '协议获取失败...' }
      }
      this.$layer.open({
        type: 1,
        skin: 'layer-register',
        title: '注册协议',
        area: ['800px', '600px'],
        scrollbar: false,
        btn: ['取消', '同意并继续'],
        btnAlign: 'c',
        id: 'LAY_layuipro',
        yes: () => {
          this.$router.replace('/')
        },
        btn2: () => {
          this.agreed = true
        },
        cancel: () => {
          this.$router.replace('/')
        },
        content: `<div style="padding: 15px">${this.protocol.content}</div>`
      })
    }
  }
}
</script>

<style lang="scss" scoped>
@import "../assets/styles/color";
.have-account {
  font-size: 16px;
  float: right;
  margin-top: 24px;
  color: #999;
  a {
    color: $color-main
  }
}
.register-content {
  border-top: 2px solid $color-main;
  padding-top: 50px;
  margin-bottom: 50px;
}
.register-content /deep/ .el-form {
  width: 400px;
  margin: 0 auto;
  .el-form-item {
    position: relative;
    margin-bottom: 30px;
    border: 1px solid #ddd;
    &.is-error {
      border-color: #f56c6c
    }
    &.is-error .el-input__inner {
      color: #f56c6c
    }
    &:hover {
      border-color: #999
    }
  }
  .el-input__inner {
    border: none
  }
  .el-form-item__label {
    letter-spacing: 3px;
    &:before {
      content: '' !important
    }
  }
  .vali-code .el-form-item__label, .sms-code .el-form-item__label {
    letter-spacing: 1px
  }
  .sms-code .el-input-group__append {
    width: 70px;
    text-align: center;
    .count-down-btn {
      padding: 0;
    }
  }
  .is-error .el-form-item__label {
    color: #f56c6c
  }
  .el-form-item__label, .el-form-item__content {
    line-height: 50px
  }
  .el-form-item__error {
    padding-top: 9px
  }
  .vali-code {
    .el-input-group__append {
      width: 100px;
      padding: 0;
      background-color: transparent;
      border: none;
      position: relative;
      img {
        width: 100%;
        height: 50px;
        cursor: pointer;
        position: absolute;
        top: -6px;
        left: 0;
      }
    }
  }
  .sms-code .el-input-group__append {
    background-color: transparent;
    border: none;
  }
  .register-btn {
    width: 400px;
    height: 52px;
    background-color: $color-main;
    color: #fff;
    font-size: 18px;
    cursor: pointer;
    border-radius: 2px;
    &:hover {
      background-color: darken($color-main, 10%)
    }
  }
}
/deep/ {
  .count-down-btn {
    line-height: 40px !important;
  }
  .el-input-group--append {
    vertical-align: middle !important;
  }
}
</style>
<style lang="scss">
@import "../assets/styles/color";
.layer-register {
  .layui-layer-title {
    text-align: center;
    font-size: 16px;
  }
  .layui-layer-content {
    line-height: 30px;
  }
  .layui-layer-btn a {
    min-width: 80px;
    height: 35px;
    line-height: 35px;
  }
  .layui-layer-btn0 {
    background-color: #e3e4e5;
    border-color: #e3e4e5;
    color: #999
  }
  .layui-layer-btn1 {
    background-color: $color-main;
    border-color: $color-main;
    color: #fff;
  }
}
</style>
